﻿Imports System.Globalization
Imports System.Security.Principal
Imports myBookmarks.Core
Imports myBookmarks.Infrastructure
Namespace myBookmarks.Web


    <HandleError()> _
    Public Class AccountController
        Inherits BaseController
        Private _userservice As IUserService
        Private _emailSender As IEmailSender
        Private _settings As IConfigurationSettings

        Public Sub New(ByVal userservice As IUserService, ByVal emailsender As IEmailSender, ByVal settings As IConfigurationSettings)
            MyBase.New(userservice, settings)
            _userservice = userservice
            _settings = settings
            _emailSender = emailsender
        End Sub

        ' GET: /Login
        Function Login() As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.ReturnUrl = If(Request.QueryString("ReturnUrl"), String.Empty)
            viewdata.Title = "Log In"
            Return View(viewdata)
        End Function

        <AcceptVerbs(HttpVerbs.Post)> _
        Function Login(ByVal email As String, ByVal password As String, ByVal rememberMe As Boolean, ByVal ReturnUrl As String) As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.ReturnUrl = ReturnUrl
            viewdata.Title = "Log In"
            If Not ValidateLogOn(email, password) Then
                Return View(viewdata)
            End If

            FormsAuthentication.SetAuthCookie(email, rememberMe)

            If Not String.IsNullOrEmpty(ReturnUrl) Then
                Return Redirect(ReturnUrl)
            Else
                Return RedirectToAction("Index", "Bookmark")
            End If

        End Function
        ' GET: /Logout
        Function Logout() As ActionResult
            FormsAuthentication.SignOut()
            Return RedirectToAction("Login", "Account")
        End Function
        ' GET: /Register
        Function Register() As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.Title = "Register"
            Return View(viewdata)
        End Function


        <AcceptVerbs(HttpVerbs.Post)> _
        Function Register(ByVal email As String, ByVal password As String, ByVal confirmPassword As String) As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.Title = "Register"
            If ValidateRegistration(email, password, confirmPassword) Then
                If _userservice.DoesUsernameExists(email) Then
                    ModelState.AddModelError("email", "Email already taken.Please provide a different email.")
                Else
                    Dim user As User = _userservice.CreateUser(email, password)
                    FormsAuthentication.SetAuthCookie(user.Email, False)
                    Return RedirectToAction("Index", "Bookmark")
                End If
            End If
            Return View(viewdata)
        End Function
        ' GET: /LostPassword
        Function LostPassword() As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.Title = "Forgot Password"
            Return View(viewdata)
        End Function

        <AcceptVerbs(HttpVerbs.Post)> _
         Function LostPassword(ByVal email As String) As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.Title = "Reset Password"

            If String.IsNullOrEmpty(email) Then
                ModelState.AddModelError("email", "You must specify an email.")
                Return View(viewdata)
            End If
            If Not _userservice.DoesUsernameExists(email) Then
                viewdata.FlashMessage = "The user is not a valid user."
                Return View(viewdata)
            End If
            Dim user As User = _userservice.GetUserByUsername(email)
            user.ResetPasswordToken = Guid.NewGuid()
            _userservice.SaveUser(user)
            Dim reseturl As String = String.Concat(Settings.RootUrl, Url.RouteUrl("ResetPassword", New With {.reset = user.ResetPasswordToken.ToString}))
            _emailSender.SendPasswordResetEmail(user.Email, user.ToString, reseturl)
            viewdata.FlashMessage = "An email has been sent to your account regarding how to reset the password."
            Return View(viewdata)
        End Function


        ' GET: /ResetPassword
        Function ResetPassword(ByVal reset As String) As ActionResult
            If String.IsNullOrEmpty(reset) Then
                Return RedirectToAction("Login")
            End If
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.Title = "Reset Password"
            viewdata.FlashMessage = "Reset Password"
            viewdata.ResetPasswordToken = reset
            Return View(viewdata)
        End Function
    

        <AcceptVerbs(HttpVerbs.Post)> _
      Function ResetPassword(ByVal email As String, ByVal password As String, ByVal confirmPassword As String, ByVal reset As String) As ActionResult
            Dim viewdata As AccountViewModel = CreateViewModel(Of AccountViewModel)()
            viewdata.Title = "Reset Password"
            If Not _userservice.DoesUsernameExists(email) Then
                viewdata.FlashMessage = "The user is not a valid user."
                Return View(viewdata)
            End If
            Dim user As User = _userservice.GetUserByUsername(email)
            If Not user.ResetPasswordToken.HasValue Then
                viewdata.FlashMessage = "The user does not have requested a password reset."
                Return View(viewdata)
            End If
            If Not ValidateRegistration(email, password, confirmPassword) Then
                Return View(viewdata)
            End If
            If Not user.ResetPasswordToken.ToString.Equals(reset) Then
                viewdata.FlashMessage = "The password reset request expired."
                Return View(viewdata)
            End If

            _userservice.ChangePassword(user, password)
            user.ResetPasswordToken = Nothing
            _userservice.SaveUser(user)

            TempData(TempDataKeys.Message) = "Password reset successfull.Please login with your new password."

            Return RedirectToAction("Login")
        End Function



#Region "Validation Methods"

        Private Function ValidateLogOn(ByVal email As String, ByVal password As String) As Boolean
            Dim isValid As Boolean = True
            If String.IsNullOrEmpty(email) Then
                isValid = False
                ModelState.AddModelError("email", "You must specify a email.")
            End If
            If isValid Then
                If Not Helpers.IsEmail(email) Then
                    isValid = False
                    ModelState.AddModelError("email", "You must specify a valid email.")
                End If
            End If
            If String.IsNullOrEmpty(password) Then
                isValid = False
                ModelState.AddModelError("password", "You must specify a password.")
            End If

            If isValid Then
                Dim user As User = _userservice.GetUserByUsername(email)
                If user Is Nothing Then
                    ModelState.AddModelError("_FORM", "The email or password provided is incorrect.")
                    Return False
                End If
                If Not _userservice.ValidateUser(user, password) Then
                    ModelState.AddModelError("_FORM", "The email or password provided is incorrect.")
                End If
            End If
            Return ModelState.IsValid
        End Function

        Private Function ValidateRegistration(ByVal email As String, ByVal password As String, ByVal confirmPassword As String) As Boolean
            Dim isvalid As Boolean = True
            If String.IsNullOrEmpty(email) Then
                ModelState.AddModelError("email", "You must specify a email.")
            End If
            If isvalid Then
                If Not Helpers.IsEmail(email) Then
                    ModelState.AddModelError("email", "You must specify a valid email.")
                End If
            End If
            If String.IsNullOrEmpty(password) Then
                ModelState.AddModelError("password", "You must specify a valid password.")
            End If
            If Not String.Equals(password, confirmPassword, StringComparison.Ordinal) Then
                ModelState.AddModelError("_FORM", "The new password and confirmation password do not match.")
            End If

            Return ModelState.IsValid
        End Function



#End Region

    End Class
End Namespace